#include <func.h>

#define N 1000000
int main()
{
    int shmid;
    //第一次是创建，如果是另外一个进程，就是通过shmget获取shmid
    shmid=shmget(1000,4096,0600|IPC_CREAT);
    ERROR_CHECK(shmid,-1,"shmget");
    //连接到本进程的进程地址空间内
    int *p=(int*)shmat(shmid,NULL,0);
    p[0]=0;
    //获取key为1000的信号量集合
    int sem_id=semget(1000,1,IPC_CREAT|0600);
    ERROR_CHECK(sem_id,-1,"semget");
    //信号量要初始化为1
    int ret=semctl(sem_id,0,SETVAL,1);
    ERROR_CHECK(ret,-1,"semctl");
    struct sembuf P;
    P.sem_num = 0;//信号量值在集合中的下标
    P.sem_op = -1;//信号量值修改
    P.sem_flg = SEM_UNDO;//如果P操作被终止，会自动恢复
    struct sembuf V;
    V.sem_num = 0;//信号量值在集合中的下标
    V.sem_op = 1;//信号量值修改
    V.sem_flg = SEM_UNDO;//如果V操作被终止，会自动恢复
    if(!fork())
    {
        int i;
        for(i=0;i<N;i++)
        {
            semop(sem_id,&P,1);//原子操作
            p[0]++;//不是原子操作
            semop(sem_id,&V,1);
        }
        exit(0);
    }else{
        int i;
        for(i=0;i<N;i++)
        {
            semop(sem_id,&P,1);
            p[0]++;
            semop(sem_id,&V,1);
        }
        wait(NULL);
        printf("p[0]=%d\n",p[0]);
        return 0;
    }
}
